#使用数学表达式解析库sympy求值
import math
from sympy import sympify, pi, E ,Integer,Float

def safe_eval(expr: str):
    """
    使用 sympy 安全解析数学表达式，支持 π, e 常量和自定义函数：
      - factorial(n)
      - root(n, x)
      - log(x, base)
    """
    try:
        # 注册常量与函数
        local_dict = {
            'π':          pi,
            'e':          E,
            'factorial':  factorial,
            'root':       root,
            'log':        log_custom,
        }
        # 先解析为 Sympy 表达式或直接调用到自定义函数
        parsed = sympify(expr, locals=local_dict)

        # 如果是 Sympy 对象，调用 evalf()；如果是原生数值则直接返回
        try:
            result = parsed.evalf()
        except AttributeError:
            result = parsed

        return result
    except Exception:
        return "错误"

def factorial(n):
    try:
        ni = int(n)
    except (TypeError, ValueError):
        raise ValueError("阶乘只支持非负整数")
    if ni < 0:
        raise ValueError("阶乘只支持非负整数")
    return Integer(math.factorial(ni))

def root(x, y):
    #root(x,n),x的n次方根
    if y == 0:
        raise ValueError("根指数不能为 0")
    return x ** (1 / y)

def log_custom(x, base):
    xf, bf = float(x), float(base)
    if xf <= 0 or bf <= 0 or bf == 1:
        raise ValueError("对数的值与底必须为正,且底不能等于1")
    return Float(math.log(xf, bf))
